<template>
  <div class="ace-container">
    <!-- 官方文档中使用id，这里禁止使用，在后期打包后容易出现问题，使用 ref 或者 DOM 就行 -->
    <div ref="aceContainerRef" class="ace-editor" />
  </div>
</template>

<script setup name="CodeEditor">
import ace from "ace-builds";
/* 启用此行后webpack打包回生成很多动态加载的js文件，不便于部署，故禁用！！
     特别提示：禁用此行后，需要调用ace.config.set('basePath', 'path...')指定动态js加载URL！！
   */
//import 'ace-builds/webpack-resolver'
import "ace-builds/src-min-noconflict/theme-monokai"; // 默认设置的主题
import "ace-builds/src-min-noconflict/theme-sqlserver"; // 新设主题
import "ace-builds/src-min-noconflict/mode-javascript"; // 默认设置的语言模式
import "ace-builds/src-min-noconflict/mode-json"; //
import "ace-builds/src-min-noconflict/mode-css"; //
// import "ace-builds/src-min-noconflict/ext-language_tools";
// import { ACE_BASE_PATH } from '@/utils/config'

const props = defineProps({
  readonly: {
    type: Boolean,
    default: false
  },
  mode: {
    type: String,
    default: "javascript"
  },
  theme: {
    type: String,
    default: "sqlserver"
  },
  autoCompletion: {
    //是否开启语法检查，默认开启
    type: Boolean,
    default: true
  }
});
const emits = defineEmits(["update"]);
const aceEditor = ref(null);
const _value = defineModel();
const aceContainerRef = ref(null);

const modeOptions = {
  css: "ace/mode/css",
  yaml: "ace/mode/yaml",
  json: "ace/mode/json",
  javascript: "ace/mode/javascript"
};

const themeOptions = {
  sqlserver: "ace/theme/sqlserver",
  monokai: "ace/theme/monokai"
};

//解决光标位置问题
// watchEffect(() => {
//   if (_value.value && aceEditor.value) {
//     //aceEditor.setValue调用后默认会全选所有文本内容，需要对光标进行特殊处理
//     const position = aceEditor.value.getCursorPosition();
//     aceEditor.value.clearSelection();
//     aceEditor.value.moveCursorToPosition(position);
//   }
// });

//解决光标位置问题
// watch([_value.value], newcode => {
//   //aceEditor.setValue调用后默认会全选所有文本内容，需要对光标进行特殊处理
//   // 缓存光标位置
//   const position = aceEditor.value.getCursorPosition();
//   setValue(newcode);
//   aceEditor.value.clearSelection();
//   aceEditor.value.moveCursorToPosition(position);
// });

const init = () => {
  ace.config.set(
    "basePath",
    "https://ks3-cn-beijing.ksyun.com/vform2021/ace-mini"
  );
  aceEditor.value = ace.edit(aceContainerRef.value, {
    maxLines: 20, // 最大行数，超过会自动出现滚动条
    minLines: 5, // 最小行数，还未到最大行数时，编辑器会自动伸缩大小
    fontSize: 14, // 编辑器内字体大小
    theme: themeOptions[props.theme], // 默认设置的主题
    mode: modeOptions[props.mode], // 默认设置的语言模式
    tabSize: 2, // 制表符设置为2个空格大小
    readOnly: props.readonly,
    highlightActiveLine: true,
    value: _value.value
  });
  aceEditor.value.setOptions({
    enableBasicAutocompletion: true,
    enableSnippets: true, // 设置代码片段提示
    enableLiveAutocompletion: true, // 设置自动提示
    showInvisibles: false
  });
  const acData = [
    {
      meta: "VForm API",
      caption: "getWidgetRef",
      value: "getWidgetRef()",
      score: 1
    },
    {
      meta: "VForm API",
      caption: "getFormRef",
      value: "getFormRef()",
      score: 1
    }
  ];
  //添加自定义代码提示！！
  ace.config.loadModule("ace/ext/language_tools", langTools => {
    langTools.addCompleter({
      getCompletions: function (editor, session, pos, prefix, callback) {
        if (prefix.length === 0) {
          return callback(null, []);
        } else {
          return callback(null, acData);
        }
      }
    });
  });
  changeMode(props.mode);
  if (!props.autoCompletion) {
    aceEditor.value.getSession().setUseWorker(false);
  }
  //编辑时同步数据
  aceEditor.value.getSession().on("change", ev => {
    _value.value = aceEditor.value.getValue();
  });
};

onMounted(() => {
  init();
});

const getEditorAnnotations = () => {
  return aceEditor.value.getSession().getAnnotations();
};

const changeMode = modeName => {
  aceEditor.value.getSession().setMode(modeOptions[modeName]);
};

const setValue = val => {
  aceEditor.value.setValue(val);
};

defineExpose({
  setValue,
  changeMode
});
</script>

<style lang="scss" scoped>
.ace-editor {
  position: relative;
  min-height: 400px;
  height: 500px;
  border: 1px solid #ccc;
  border-radius: 2px;
}
</style>
